#include "stdafx.h"
#include "RichEditView.h"
#include "SkCanvas.h"
#include "EditText.h"
#include "WidgetWin.h"

RichEditView::RichEditView(View* parent)
	: View(parent)
	, font_height_(16)
	, paint_size_(0, 0)
	, animation_(0, 500)
	, font_width_(0)
{
	// canvas_ = std::shared_ptr<SkCanvas>(new SkCanvas(1, 1));
	font_ = std::shared_ptr<SkFont>(new SkFont(std::wstring(L"����")));
	memset(&cursor_pos_, 0, sizeof(cursor_pos_));
}


RichEditView::~RichEditView()
{
}

void RichEditView::mouseEntry()
{
	ATLTRACE("[%s][%d]\r\n", __FUNCTION__, __LINE__);
	::SetCapture(WidgetWin::getInstance().getNativeHwnd());
	cursor_ = ::GetCursor();
	::SetCursor(LoadCursor(NULL, IDC_IBEAM));
}

void RichEditView::mouseLeave()
{
	ATLTRACE("[%s][%d]\r\n", __FUNCTION__, __LINE__);

	::SetCursor(cursor_);
	::ReleaseCapture();
}

void RichEditView::gotFocus()
{
	if (!animation_.isAnimate())
	{
		animation_.start(this);
	}
	updateView();
}

void RichEditView::loseFocus()
{
	if (animation_.isAnimate())
	{
		animation_.cancel();
	}
}

void RichEditView::setText(std::wstring& text)
{

}

std::wstring RichEditView::getText()
{
	return std::wstring();
}

void RichEditView::append(std::wstring& append_text)
{

}

void RichEditView::append(wchar_t append_text)
{

}


bool RichEditView::paint(SkCanvas* canvas)
{
	paintBackground(canvas);

	if (getStatus() == STATUS_FOCUS)
	{
		paintFocus(canvas);
	}

	paintFrontground(canvas);
	paintCursorBlink(canvas);
	return true;

}

bool RichEditView::paintBackground(SkCanvas* canvas)
{
	if (canvas)
	{
		canvas->FillRect(SkColor(50, 50, 50), 0, 0, Width(), Height());
		return true;
	}
	return false;

}

bool RichEditView::paintFrontground(SkCanvas* canvas)
{
	if (canvas)
	{
		canvas->setFont(*font_);

		font_width_ = canvas->getFontWidth();
		font_height_ = canvas->getFontHeight();
		

		int x = 0;
		int y = Height() - paint_size_.height();
		if (y > 0)
		{
			y = 0;
		}
		// int lastLineHeight = 0;
		std::wstring str_line;
		for (std::list<std::shared_ptr<EditObject>>::iterator iter = text_.begin(); iter != text_.end(); ++iter)
		{
			// bool is_need_paint = false;
			// check spec char
			wchar_t ch = (*iter)->getText();
			// gfx::Size size = (*iter)->getSize();
			if (ch ==L'\r') // return
			{
				x = 0;
			}
			else if (ch == L'\n')
			{
				ATLTRACE("[%s][%d}\r\n", __FUNCTION__, __LINE__);
				// draw text
#if 0
				canvas->TextOut(str_line, x + X(), y + Y());
#else
				gfx::Size size = canvas->measureString(str_line, *font_);
				canvas->drawText(str_line, *font_, SkColor(255, 255, 255),
					0, y, size.width(), size.height());
#endif
				y += font_height_;
				str_line = L"";
			}
			else
			{
				str_line += ch;
			}

			// x += size.width();
		}

		if (str_line.size())
		{
			ATLTRACE("[%s][%d}\r\n", __FUNCTION__, __LINE__);
			// draw text
			// SetTextColor(canvas->getCurrentGraphics()->GetHDC(), RGB(255, 0, 0));
			// TextOut(canvas->getCurrentGraphics()->GetHDC(), 0, 0, str_line.c_str(), str_line.length());
#if 0
			canvas->TextOut(str_line, x + X(), y + Y());
#else
			gfx::Size size = canvas->measureString(str_line, *font_);
			canvas->drawText(str_line, *font_, SkColor(255, 255, 255),
				0, y, size.width() + 10, font_height_);
#endif
		}


		return true;
	}
	return false;

}

/*
gfx::Size RichEditView::calcTotalSize()
{
	int max_x = 0;
	int x = 0;
	int y = 0;
	std::wstring str_line;
	for (std::list<std::shared_ptr<EditObject>>::iterator iter = text_.begin(); iter != text_.end(); ++iter)
	{
		wchar_t ch = (*iter)->getText();
		if (ch == L'\r') // return
		{
			x = 0;
		}
		else if (ch == L'\n')
		{
			ATLTRACE("[%s][%d}\r\n", __FUNCTION__, __LINE__);
			// draw text
			// gfx::Size size = canvas_->measureString(str_line, *font_);
			x = size.width();
			max_x = max(x, max_x);
			y += font_height_;
			str_line = L"";
		}
		else
		{
			str_line += ch;
		}

		// x += size.width();
	}

	if (str_line.size())
	{
		ATLTRACE("[%s][%d}\r\n", __FUNCTION__, __LINE__);
		// draw text
		// gfx::Size size = canvas_->measureString(str_line, *font_);
		x = size.width();
		max_x = max(x, max_x);
	}


	return gfx::Size(max_x, y+font_height_);
}
*/

bool RichEditView::paintBorder(SkCanvas* canvas)
{
	return false;
}

bool RichEditView::paintHover(SkCanvas* canvas)
{
	return false;
}

bool RichEditView::paintFocus(SkCanvas* canvas)
{
	return false;
}

bool RichEditView::paintCursorBlink(SkCanvas* canvas)
{
	ATLTRACE("[%s][%d]\r\n", __FUNCTION__, __LINE__);

#if 1
	if (canvas)
	{
		int cursor_point_x = cursor_pos_.xpos * font_width_;
		int cursor_point_y = cursor_pos_.line * font_height_;
		ATLTRACE("drawLine [%s][%d][%d][%d]\r\n", __FUNCTION__, __LINE__, cursor_point_x, cursor_point_y);
		if (animation_.isAnimate())
		{
			if (animation_.getCalc() % 2 == 1)
			{
				canvas->drawLine(SkColor(255, 255, 255), cursor_point_x, cursor_point_y, cursor_point_x, cursor_point_y + font_height_);
			}
		}

		return false;
	}
#endif
	return false;
}

bool RichEditView::processKeyEvent(KeyEvent& event)
{
	wchar_t ch = static_cast<wchar_t>(event.key_code);
	// Back Space
	if (ch == 0x08)
	{
		if (text_.size() > 0)
		{
			std::list<std::shared_ptr<EditObject>>::reverse_iterator iter = text_.rbegin();
			if ((*iter)->getText() == L'\n')
			{
				text_.pop_back(); // pop_back again.
				cursor_pos_.line--;
				cursor_pos_.xpos = 0;
			}
			else
			{

			}

			if (text_.size() > 0)
			{
				text_.pop_back();
				// cursor_pos_.line--;
				cursor_pos_.xpos--;
				if (cursor_pos_.xpos<0)
				{
					SK_ASSERT("cursor_pos_" );
					cursor_pos_.xpos = 0;
				}
			}
		}
	}
	else
	{
		std::shared_ptr<EditObject> text = std::shared_ptr<EditObject>(new EditText(ch));
		text_.push_back(text);
		if (ch==L'\r')
		{
			ch = L'\n';
			std::shared_ptr<EditObject> text = std::shared_ptr<EditObject>(new EditText(ch));
			text_.push_back(text);
			cursor_pos_.line++;
			cursor_pos_.xpos = 0;

		}
		else
		{
			// cursor_pos_.line;
			cursor_pos_.xpos++;
		}
	}


	// paint_size_ = calcTotalSize();
	updateView();

	return true;
}
